<html>
<script>


    // // 初始化对象的计数器属性
    // var uniqueInterger = {
    //     counter:0
    // };

    // // 每次调用这个函数都会返回一个不同的整数
    // // 它使用一个属性来记住下一个将要返回的值
    // function upiqueInteger() {
    //     return uniqueInterger.counter ++; // 先返回计数器的值，然会计数器自增
    // }

    // console.log(upiqueInteger(),uniqueInterger.counter);

    // // 来看另一个例子
    // // 计算阶乘
    // function factorial(n) {
    //     if(isFinite(n) && n ==Math.round(n)) {
    //         console.log(factorial);
    //         if(!(n in factorial)) {
    //             factorial[n] = n * factorial(n-1);
    //         }
    //         return factorial[n];
    //     }
    //     else return NaN; // 如果输入有误
    // }

    // factorial[1] = 1; // 初始化缓存以保存这种情况
    // console.log(factorial(4));

    // var extend = (function () {
    //     // 在修复之前。首先检测是否存在bug
    //     console.log("start");
    //     console.log(arguments);
    //     for (var p in {}) {
    //         console.log("11");
    //         return function extend(o) {
    //             console.log("o");
    //             for (var i; i < arguments.length; i++) {
    //                 console.log(o);
    //                 var source = arguments[i];
    //                 for (var prop in source) {
    //                     o[prop] = source[prop];
    //                 }
    //             }
    //             return o;
    //         };
    //     }



    //     return function patched_extend(o) {
    //         console.log("22");
    //         for (var i = 1; i < arguments.length; i++) {
    //             var source = arguments[i];
    //             // 复制所有的可枚举性
    //             for (var prop in source) {
    //                 o[prop] = source;
    //             }
    //             // 现在检测特殊属性
    //             for (var j = 0; j < protoprops.length; j++) {
    //                 prop = protoprops[j];
    //                 if (source.hasOwnProperty(prop)) {
    //                     o[prop] = source[prop]
    //                 }
    //             }
    //             return o;
    //         }
    //     };
    //     // 这个列表列出了需要检测的特殊属性
    //     var protoprops = ["toString", "valueOf", "constructor", "hasOwnProperty",
    //         "isPrototypeOf", "propertyIsEnumerable", "toLocaleString"];
    // }());
    // var h = { x: 1, y: 2, z: 3 };
    // console.log(extend(h));

    // 这个函数使用argument.callee, 因此它不能在严格模式下工作


    // var o = { x: 1 };
    // var g = f.bind(o);
    // console.log(g(2));
    // //  g(2) // =>3.

    // 可以通过代码轻易实现这种绑定
    // function bind1(f, o) {

    //     console.log(o, arguments);
    //     console.log(f.apply(o, arguments));

    //     // if (f.bind) {
    //     console.log("this.x", this.x);
    //     //     console.log(f.bind)
    //     //     return f.bind(o);
    //     // } else {
    //     let a = function () { return f.apply(o, arguments) }
    //         console.log(a);
    //     console.log(function () { return f.apply(o, arguments) });
    //     return function () {
    //         return f.apply(o, arguments);

    //     };

    //     // }
    // }

    // var y = { x: 1 };
    // var g = bind1(function f(y) {
    //     return this.x + y;
    // }, y);

    // console.log(g(2));

    // // var b = function f(y) {
    // //     console.log(this.x)
    // //     return this.x + y;
    // // }
    // // console.log(b(10))

    // 函数性编程

    // var sum =function(x,y) {return x + y}; // 返回两个实参的和值
    // // 创建一个类似sum的新函数，但this的值绑定到null
    // // 并且第一个参数绑定到1 ，这个新的函数期望只传入一个实参
    // var succ = sum.bind(null,1);
    // // succ(2);

    // function f(y,z) {return this.x + y + z};
    // var g = f.bind({x: 1},2);
    // console.log(g(3));
    

    // ECMAScript3版本的Function.bind()方法

    if(!Function.prototype.bind) {
        Function.prototype.bind = function(o/*，arg */) {
            // 将this和arguments的值保存至变量中
            // 以便在后面嵌套的函数中可以使用它们
            var self = this, boundArgs = arguments;

            // bind() 方法的返回值是一个函数
            return function() {
                var args =[], i;
                for(i = 1; i < boundArgs.length; i++) {
                    args.push(boundArgs[i]);
                }
                for(i = 0; i<arguments.length; i++) {
                    arguments.push(arguments[i]);
                }
                // 现在将self作为o的方法来调用，传入这些实参
                return self.apply(o,args);
            };
        };
    }
</script>



<head>
    <title>放置文章标题</title>
</head>

<body>

</body>

</html>